package com.example.rabbitmq.config.listener;

import com.example.rabbitmq.config.comsume.DefaultRabbitConsume;
import com.example.rabbitmq.config.comsume.RabbitConsume;
import com.example.rabbitmq.config.message.RabbitData;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.amqp.utils.SerializationUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.util.List;

/**
 * @Author dengsd
 * @Date 2021/11/5 14:30
 */
@Configuration("rabbitMessageListener")
public class RabbitMessageListener implements ChannelAwareMessageListener {
    private List<RabbitConsume> delegate;
    private RabbitConsume defaultConsume;
    @Autowired
    public RabbitMessageListener(List<RabbitConsume> delegate) {
        this.delegate = delegate;
        this.defaultConsume = new DefaultRabbitConsume();
    }
    @Override
    public void onMessage(Message message, Channel channel) throws IOException {
        try {
            byte[] body = message.getBody();
            RabbitData rabbitData =  (RabbitData)SerializationUtils.deserialize(body);
            boolean ack = false;
            for (RabbitConsume rabbitConsume : delegate) {
                if (rabbitConsume.support(rabbitData.getMessage().getClass())) {
                    handler(rabbitConsume,rabbitData,message,channel);
                    ack = true;
                }
            }
            if(!ack){
                handler(defaultConsume,rabbitData,message,channel);
            }
        }catch (Exception e){
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        }


    }

    private void handler(RabbitConsume rabbitConsume,RabbitData rabbitData,Message message,Channel channel) throws Exception{
        try {
            rabbitConsume.onSuccess(rabbitData.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            rabbitConsume.onFail(rabbitData.getMessage());
        }
        // 确认消费
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);

    }

}
